package com.libbase.utils

import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.internal.LinkedTreeMap
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter


class DataTypeAdapter : TypeAdapter<Any?>() {
    private val delegate = Gson().getAdapter(
        Any::class.java
    )

    override fun read(`in`: JsonReader?): Any? {
        return when (`in`?.peek()) {
            JsonToken.BEGIN_ARRAY -> {
                val list: MutableList<Any> = ArrayList()
                `in`.beginArray()
                while (`in`.hasNext()) {
                    read(`in`)?.let { list.add(it) }
                }
                `in`.endArray()
                list
            }
            JsonToken.BEGIN_OBJECT -> {
                val map: MutableMap<String, Any?> = LinkedTreeMap()
                `in`.beginObject()
                while (`in`.hasNext()) {
                    map[`in`.nextName()] = read(`in`)
                }
                `in`.endObject()
                map
            }
            JsonToken.STRING -> `in`.nextString()
            JsonToken.NUMBER -> {
                /**
                 * 改写数字的处理逻辑，将数字值分为整型与浮点型。
                 */
                val dbNum = `in`.nextDouble()

                // 数字超过long的最大值，返回浮点类型
                if (dbNum > Long.MAX_VALUE) {
                    return dbNum
                }

                // 判断数字是否为整数值
                val lngNum = dbNum.toLong()
                if (dbNum == lngNum.toDouble()) {
                    if (lngNum > Int.MAX_VALUE) {
                        return lngNum
                    } else {
                        lngNum.toInt()
                    }
                } else {
                    dbNum
                }
            }
            JsonToken.BOOLEAN -> `in`.nextBoolean()
            JsonToken.NULL -> {
                `in`.nextNull()
                null
            }
            else -> throw IllegalStateException()
        }
    }

    override fun write(out: JsonWriter?, value: Any?) {
        delegate.write(out, value)
    }
}